<?php
namespace App\Modules\Relationship\Services;

use App\Http\Model\Hint;
use App\Http\Services\Message\MessageServices;
use Illuminate\Support\Facades\DB;
use App\Http\Model\User;
use Illuminate\Support\Facades\Redis;
use App\Http\Services\CommonServices;
use App\Modules\Relationship\Models\RsRelationshipModel;
use App\Modules\Relationship\Models\RsRelationshipLevelModel;
use App\Modules\Relationship\Models\RelationshipTasksModel;
use App\Modules\Relationship\Models\RelationshipIntimacyLogModel;
use App\Modules\Relationship\Models\RelationshipLevelNoticeModel;
use App\Modules\Relationship\Interfaces\ModelInterface;
use App\Http\Model\FinanceUserWallet;
use App\Http\Model\FinanceDiamond;
use App\Http\Model\PropUserPack;
use App\Http\Model\PropUserPackLog;
use App\Http\Model\Prop;
use App\Http\Model\PropLog;
use App\Http\Model\UserLoginLog;
use App\Modules\Relationship\Enums\ErrorEnum;
use App\Modules\Relationship\Enums\ConstEnum;


class RsCommonService extends CommonServices {

    // 关系主表model
    protected $rsModel;

    protected $user;
    protected $rsRelationshipLevelModel;
    protected $modelNames = array(
        1 => "App\Modules\Relationship\Models\FriendsModel",
        2 => "App\Modules\Relationship\Models\SweetFriendModel",
        3 => "App\Modules\Relationship\Models\CoupleModel");

    protected $relationshipTasksModel;
    protected $financeUserWalletModel;

    protected $relationshipIntimacyLogModel;
    protected $financeDiamondModel;
    protected $propUserPackModel;
    protected $propUserPackLogModel;
    protected $propModel;
    protected $diamondModel;
    protected $propLogModel;
    protected $userPackModel;
    protected $relationshipLevelNoticeModel;
    protected $userLoginLog;


    public function __construct(){
        parent::__construct();
        $this->rsModel = new RsRelationshipModel();
        $this->user = new User();
        $this->rsRelationshipLevelModel = new RsRelationshipLevelModel();
        $this->relationshipTasksModel = new RelationshipTasksModel();
        $this->relationshipIntimacyLogModel = new RelationshipIntimacyLogModel();
        $this->financeUserWalletModel = new FinanceUserWallet();
        $this->financeDiamondModel = new FinanceDiamond();
        $this->propUserPackModel = new PropUserPack();
        $this->propModel = new Prop();
        $this->diamondModel = new FinanceDiamond();
        $this->propLogModel = new PropLog();
        $this->propUserPackLogModel = new PropUserPackLog();
        $this->relationshipLevelNoticeModel = new RelationshipLevelNoticeModel();
        $this->userLoginLog = new UserLoginLog();
    }
    // 获取主表记录
    protected function getOneRelation ($userId, $friendId) : array {
        $rsRecord = $this->rsModel->getOneRelation($userId, $friendId);
        if (!$rsRecord) {
            return [];
        }
        return $rsRecord;
    }

    protected function getOneLevel ($type, $level) {
        $levelInfo = $this->rsRelationshipLevelModel->getOneTypeRecord($type, $level);
        if (!$levelInfo) {
            throw new \Exception("等级不存在");
        }
        return $levelInfo;
    }

    protected function getAllLevel ($type) : array {
        $levelInfo = $this->rsRelationshipLevelModel->getAllLevelRecord($type);
        if (!$levelInfo) {
            throw new \Exception("等级记录不存在");
        }
        return $levelInfo;
    }

    // 通过好友类型获取分表记录
    protected function getOneRelationshipInfoByType ($type, $userId, $friendId) : array {
        $rsRecord = $this->getOneRelationshipInfo($this->modelNames[$type], $userId, $friendId);
        if (!$rsRecord) {
            throw new \Exception("好友关系已变更，退出刷新一下吧~");
        }
        return $rsRecord;
    }

    // 获取分表记录
    protected function getOneRelationshipInfo ($modelName, $userId, $friendId) : array {
        $rsRecord = self::make($modelName)->getRecord($userId, $friendId);
        if (!$rsRecord) {
            //$WebHook = config("message.module.modelCp");
            //MessageServices::text($WebHook, '异常-好友关系RsCommonService-uid'.$userId.'-fid:'.$friendId);
            // write_log(
            //     'RsCommonService'.(isCli()?'-cli':''),
            //     '[ERROR] 好友关系-getOneRelationshipInfo',
            //     ['userId'=>$userId, 'friendId'=>$friendId, 'modelName'=>$modelName]
            // );
            throw new \Exception("好友关系已变更，退出刷新一下吧~");
        }
        return $rsRecord;
    }

    // 通过好友类型获取分表记录
//    protected function getRecordAndAttrByType ($type, $rsCode) : array {
//        $rsRecord = $this->getRecordAndAttr($this->modelNames[$type], $rsCode);
//        return $rsRecord;
//    }
//
//    // 获取分表记录
//    protected function getRecordAndAttr ($modelName, $rsCode) : array {
//        $rsRecord = self::make($modelName)->getRecordAndAttr($rsCode);
//        if (!$rsRecord) {
//            // TODO 抛异常
//            throw new \Exception("xxxx");
//        }
//        return $rsRecord;
//    }

    protected function getUserInfo ($userId = 0) {
        $userInfo = null;
        if ($userId!=0) {
            $userInfo = $this->user->get_user($userId);
        } else {
            $userInfo = $this->user->get_current_user();
        }
        if (!$userInfo) {
            throw new \Exception("用户信息不存在");
        }
        return $userInfo;
    }

    // 获取好友的用户信息
    protected function getFriendUserInfo($friendId) : array {
         $friendInfo = $this->user->get_user($friendId);
         $return = array();
         if ($friendInfo) {
             $return['userId'] = $friendInfo['user_id'];
             $return['userUid'] = $friendInfo['user_uid'];
             $return['gender'] = $friendInfo['gender'];
             $return['nickname'] = $friendInfo['nickname'];
             $return['adaptImages'] = $friendInfo['adapt_images'];
             $return['cpStatus'] = $friendInfo['cp_status'];
         }
         if (!$return) {
             throw new \Exception("用户信息不存在");
         }
         return $return;
    }

    // 创建分表对象
    protected static function make ($modelName) : ModelInterface {
        $model = new $modelName();
        if ($model instanceof ModelInterface) {
            return $model;
        }
        // TODO 抛出异常
        throw new \Exception("系统异常");
    }

    // 计算天数
    protected function getDays (string $date) : int {
        $days = 0;
        if ($date<=0) return $days;
        $timeS = strtotime($date);
        $date = date("Y-m-d 00:00:00", $timeS);
        $timtData = strtotime($date);
        $chaS =abs( $timtData - time() );
        if ($chaS > 0) {
            $days = ceil($chaS / (24 * 3600));
        }
        return $days;
    }

    /**
     * 判断是否有成为CP或者密友的基础条件 1.用户都正常 2.是否是CP或密友 3.今日申请一次，4 满足好友值大于1000
     * @param $userId
     * @param $friendId
     * @param $type
     */
    protected function checkBasicConditions($userId, $friendId) {
        $rsInfo = $this->getOneRelation($userId, $friendId);
        if (!$rsInfo) {
            return 1;
        }
        if ($rsInfo['type'] != 1) {
            return $rsInfo['type'];
        }
        // 不满足好友值1000
        if ($rsInfo['intimate'] < 1000) {
            return 4;
        }
        return 0;
    }

    /**
     * 24小时没有申请
     * @return bool
     */
    protected function getReqWithin24hours () {
        return false;
    }

    /**
     * 用户当前钻石数量
     */
    protected function getUserDiamond (int $userId) : int {
        $walletInfo = $this->financeUserWalletModel->get_wallet($userId);
        $diamond = $walletInfo['diamond_balance'];
        return $diamond ?? 0;
    }

    /**
     * 扣减钻石
     */
    protected function incDiamond () {
        //$this->financeDiamondModel->inc();
        return true;
    }

    /**
     * 获取道具
     */
    protected function getProp ($userId, $propId) {
        $re = $this->propUserPackModel->checkUserPack($userId, $propId);
        return $re;
    }

    /**
     * 道具数量
     */

    protected function getPropNum ($userId, $propId) {
        $re = $this->propUserPackModel->checkUserPack($userId, $propId);
        if ($re) {
            return $re['num'];
        }
        return 0;
    }

    /**
     * 发放道具
     * @param $userId
     * @param $propId
     */
    public function grantProp ($userId, $propId, $num) {
        $grantProp = $this->propModel->grantProp($userId, $propId, 0, $num, 70);
        if (!$grantProp) {
            return Hint::ERR_DATA_UPDATE_FAIL;
        }
        return $grantProp;
    }

    /**
     * 使用道具
     */
    protected function useProp ($userId, $propId, $num = 1) {
        $prop = $this->getProp($userId, $propId);
        if (!$prop || $prop['num'] < 1) {
            return Hint::ERROR;
        }
        DB::beginTransaction();

        $propLogData = [
            'user_id' => $userId,
            'prop_id' => $propId,
            'created_at' => time(),
            'change' => -(int)$num
        ];

        // 道具使用日志
        $updateOrInsertPropLog = $this->propLogModel->updateOrInsertPropLog($propLogData);
        if (!$updateOrInsertPropLog) {
            //DB::rollBack();
            return Hint::ERR_DATA_CREATE_FAIL;
        }
        // 更新用户背包数据
        $data['user_pack_id'] = $prop['user_pack_id'];
        $data['num'] = $num;
        $updateUserPackData = $this->propUserPackModel->updateOrInsertUserPack($data, 'decrement');
        if (!$updateUserPackData) {
            return Hint::ERR_DATA_UPDATE_FAIL;
        }
        DB::commit();
    }

    protected function checkBasicInfo ($userId, $friendId) {
        $msg = '';
        $reCode = $this->checkBasicConditions($userId, $friendId);
        if ($reCode == 1) {
            $msg = "还不是好友";
        }else if ($reCode == 2) {
            $msg = "你们已经是密友啦~";
        }else if ($reCode == 3) {
            $msg = "你们已经是CP啦~";
        }else if ($reCode == 4) {
            $msg = "亲密值小于1000";
        }
        return $msg;
    }

    // 判断是否通知
    protected function checkoutIsNotice ($rsCode, $userId) {
       $re = $this->relationshipLevelNoticeModel->getRecord($rsCode, $userId);
       if ($re) {
           $this->relationshipLevelNoticeModel->deleteRecord($rsCode,$userId);
           return 1;
       }
       return 0;
    }
}